﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static L02.CzPoint;

namespace L02
{
    #region T1
    public class CzPoint
    {
        private double x;
        private double y;

        public double X { get => x; set => x = value; }
        public double Y { get => y; set => y = value; }

        public CzPoint(double x, double y)
        {
            this.x = x;
            this.y = y;
        }

        public void Move(double dx, double dy)
        {
            this.x += dx;
            this.y += dy;
        }

        public static bool operator ==(CzPoint p1, CzPoint p2)
        {
            return (p1.x == p2.x) && (p1.y == p2.y);
        }

        public static bool operator !=(CzPoint p1, CzPoint p2)
        {
            return (p1.x != p2.x) || (p1.y != p2.y);
        }

        public class Line
        {
            private double k;
            private double b;

            public double K { get => k; set => k = value; }
            public double B { get => b; set => b = value; }

            public Line(double k, double b)
            {
                this.k = k;
                this.b = b;
            }

            public void Move(double db)
            {
                this.b += b;
            }

            public Line(CzPoint p1,CzPoint p2)
            {
                if (p1 == p2)
                { throw new ArgumentException("两点不能相同"); }
                this.k = (p2.Y - p2.X) / (p2.X - p1.X);
                this.b = p2.Y = p2.X * this.k;
            }

            public bool Contains(CzPoint P)
            {
                return (P.Y == k * P.x + b);
            }

            public static bool operator ==(Line l1, Line l2)
            {
                return (l1.k == l2.k) && (l1.b == l2.b);
            }

            public static bool operator !=(Line l1, Line l2)
            {
                return (l1.k == l2.k) || (l1.b == l2.b);
            }
        }
    }
    #endregion

    #region T2
    public abstract class Vehicle
    {
        public float V { get; set; }
        public Vehicle(float v)
        {
            V = v;
        }
        public virtual void Run(float d)
        {
            Console.WriteLine("行驶{0}公里用时{1}",d,d/V);
        }
    }
    public class Car : Vehicle
    {
        public int Passenger { get; set; }
        public Car(float v, int passenger) : base(v)
        {
            this.Passenger = passenger;
        }
    }
    public class Trunk : Vehicle
    {
        public int Load { get; set; }
        public override void Run(float d)
        {
            Console.WriteLine("载重{0}时行驶时间为{1}",Load,(1+Load/100)*d/V);
        }
        public Trunk(float v) : base(v) { }
    }
    #endregion

    #region T3
    public class Triangle
    {
        private double a, b, c;

        public Triangle(double a = 1, double b = 1, double c = 1)
        {
            this.a = a;
            this.b = b;
            this.c = c;
        }

        public double A { get => a; set => a = value; }
        public double B { get => b; set => b = value; }
        public double C { get => c; set => c = value; }

        public double Perimeter()
        {
            return this.a + this.b + this.c;
        }

        public double Area()
        {
            return Math.Sqrt((Perimeter() / 2 - this.a) * (Perimeter() / 2 - this.b) * (Perimeter() / 2 - this.c));
        }
    }

    #endregion

    #region T4
    public static class Sun
    {
        public static event EventHandler OnRise;
        public static void Rise()
        {
            Console.WriteLine("太阳从东方升起...");
            if (OnRise != null)
                OnRise(null, null);
        }
    }

    public class Cock
    {
        private string name;
        public Cock(string name)
        {
            this.name = name;
            Sun.OnRise += new EventHandler(Sun_OnRise);
        }
        private void Sun_OnRise(object sender, EventArgs e)
        {
            Console.WriteLine("公鸡{0}:",name); Console.WriteLine("雄鸡一唱天下白"); this.Sing();
        }
        public event EventHandler OnSing;
        public void Sing()
        {
            Console.WriteLine("喔喔喔…");
            if (OnSing != null)
            {
                OnSing(this, null);
            }
        }
    }

    public class Host
    {
        private string name;
        public Host(string name)
        {
            this.name = name;
        }
        public event EventHandler OnGetup;
        public void Getup()
        {
            Console.WriteLine("日出而作…");
            if (OnGetup != null)
            {
                OnGetup(this, null);
            }
        }
        public void Foster(Cock c1)
        {
            c1.OnSing += new EventHandler(c1_OnSing);
        }
        private void c1_OnSing(object sender, EventArgs e)
        {
            Console.WriteLine("主人{0}:",name); Console.WriteLine("闻鸡起舞！"); this.Getup();
        }
    }

    public class Dog
    {
        private string name;
        private Host owner;
        public Host Owner
        {
            get { return this.owner; }
            set { this.owner = value;this.owner.OnGetup += new EventHandler(owner_OnGetup); }
        }
        public Dog(string name)
        {
            this.name = name;
        }
        private void owner_OnGetup(object sender, EventArgs e)
        {
            Console.WriteLine("{0}",name);
            Console.WriteLine("汪汪...主人起床了，我也该起床了");
        }
    }

    public class Cat
    {
        private string name;
        private Host owner;
        public Host Owner
        {
            get { return this.owner; }
            set { this.owner = value; this.owner.OnGetup += new EventHandler(owner_OnGetup); }
        }
        public Cat(string name)
        {
            this.name = name;
        }
        private void owner_OnGetup(object sender, EventArgs e)
        {
            Console.WriteLine("{0}", name);
            Console.WriteLine("喵喵...主人起床了，我也该起床了");
        }
    }

    #endregion

    class Program
    {
        static void Main(string[] args)
        {
            #region T1
            CzPoint pp1 = new CzPoint(2, 3);
            CzPoint pp2 = new CzPoint(3, 2);
            Console.WriteLine("pp1和pp2相等吗？答：{0}",pp1==pp2);
            Console.WriteLine("pp1和pp2不相等吗？答：{0}", pp1 != pp2);

            pp2.Move(-1, -1);
            CzPoint pp0 = new CzPoint(0,0);
            Console.WriteLine("移动后相等吗？答：{0}",pp1==pp2);
            Console.WriteLine("移动后不相等吗？答：{0}", pp1 != pp2);
            Console.WriteLine("p<{0},{1}>",pp0.X,pp0.Y);
            CzPoint p1 = new CzPoint(1, 2);
            CzPoint p2 = new CzPoint(3, 3);
            Console.WriteLine(p1==p2);
            p1.Move(2, 1);
            Console.WriteLine(p1==p2);
            Line l1 = new Line(new CzPoint(0,0),p1);
            Console.WriteLine(l1.Contains(p2));
            Console.WriteLine(l1.Contains(new CzPoint(4,4)));
            Console.WriteLine("{0},{1}",l1.K,l1.B);
            Line l2 = new Line(1, 2);
            Console.WriteLine(l1==l2);
            l2.Move(-2);
            Console.WriteLine(l1==l2);
            #endregion

            #region T2
            Vehicle v1 = new Car(80, 5);
            v1.Run(800);
            Vehicle v2 = new Trunk(80);
            v2.Run(800);
            #endregion

            #region T3


            Triangle triangle=new Triangle(3,4,5);
            if(triangle.A+triangle.B+triangle.C<0||
                triangle.A+triangle.B<triangle.C||
                triangle.A+triangle.C<triangle.B||
                triangle.B+triangle.C<triangle.A)
                throw new ArgumentOutOfRangeException("三角形数据异常");
            else
                Console.WriteLine("这是一个三角形");
            Console.WriteLine("三角形周长：{0}",triangle.Perimeter());
            Console.WriteLine("三角形面积：{0}",triangle.Area());
            #endregion

            #region T4
            Cock cock = new Cock("花花");
            Host host = new Host("祖逖");
            host.Foster(cock);
            Dog dog = new Dog("阿黄");
            dog.Owner = host;
            Cat cat = new Cat("阿咪");
            cat.Owner = host;
            Sun.Rise();

            #endregion

            Console.ReadKey();
        }

    }
}
